home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / knowhow4 / editl.cpp < prev    next >
C/C++ Source or Header  |  1994-10-10  |  8KB  |  301 lines

  1. // EDITL.CPP
  2. #include <stdlib.h>
  3. #include "editl.h"
  4. #include "cursor.h"
  5.  
  6. EditLine::EditLine(loc pos, int l, int max_len, BORDERS b_type, int pat,
  7.     int insert)
  8.     : FormLine(b_type)
  9.     {
  10.     ins = insert;
  11.     string = strdup("");
  12.     xy = pos;
  13.     len = l - textX(area[border_type].origin.X
  14.         + area[border_type].corner.X);
  15.     ret = pointTo = action_type = 0;
  16.     if(max_len == 0)
  17.     maxlen = 255;
  18.     else
  19.     maxlen = max_len;
  20.     pattern = pat;
  21.     }
  22. /////////////////////////
  23. void EditLine::bksp(int* cur_pos, int *vis_pos)
  24.     {
  25.     if(*cur_pos == strlen(string))
  26.     del(cur_pos, vis_pos);
  27.     left(cur_pos, vis_pos);
  28.     if(*cur_pos != strlen(string))
  29.     del(cur_pos, vis_pos);
  30.     }
  31. /////////////////////////////
  32. void EditLine::home(int* cur_pos, int* vis_pos)
  33.     {
  34.     *cur_pos = *vis_pos = 0;
  35.     redraw_string(xy, 0, 0);
  36.     }
  37. //////////////////////
  38. void EditLine::redraw_string(loc pos, int tmp, int start)  // tmp - begin
  39.     {                                            // start - length
  40.     char* str = (char*)malloc(len + 2);          // from begin
  41.     strncpy(str, string + tmp, len - start);
  42.     str[len - start/* + 1*/] = '\0';
  43.     FormLine::outtextxy(pos, len - start, str, pattern);
  44.     delete str;
  45.     }
  46. ////////////////////////
  47. void EditLine::repose(rect new_coord)
  48.     {
  49.     xy = new_coord.origin;
  50.     len = new_coord.width() - 1;
  51.     }
  52. ////////////////////////
  53. rect EditLine::bound()
  54.     {
  55.     return rect(screenLocLT(xy),
  56.     loc(screenXR(xy.X + len) + area[border_type].origin.X
  57.       + area[border_type].corner.X,
  58.         screenYB(xy.Y) + pScreenSet->standart_height + 2
  59.         + area[border_type].origin.Y + area[border_type].corner.Y));
  60.     }
  61. /////////////////////////
  62. void EditLine::put_string(char* str )
  63.     {
  64.     if(string)
  65.     delete string;
  66.     string = strdup(str);
  67.     }
  68. ////////////////////////
  69. void EditLine::end(int* cur_pos, int* vis_pos)
  70.     {
  71.     *cur_pos = (strlen(string) < maxlen)
  72.           ? strlen(string) : strlen(string) - 1;
  73.     *vis_pos = strlen(string) > len ?
  74.           strlen(string) - len : 0;
  75.     redraw_string(xy, *vis_pos);
  76.     }
  77. /////////////////////////
  78. void EditLine::hilite()
  79.     {
  80.     Carcase::show(PRESS_BORDER, rect(screenXL(xy.X),
  81.         screenYT(xy.Y),
  82.         screenXR(xy.X + len) + area[border_type].origin.X
  83.         + area[border_type].corner.X,
  84.         screenYB(xy.Y) + pScreenSet->standart_height + 2
  85.         + area[border_type].origin.Y + area[border_type].corner.Y));
  86.     }
  87. ///////////////////////
  88. void EditLine::unhilite()
  89.     {
  90.     Carcase::show(border_type, rect(screenXL(xy.X),
  91.         screenYT(xy.Y),
  92.         screenXR(xy.X + len) + area[border_type].origin.X
  93.         + area[border_type].corner.X,
  94.         screenYB(xy.Y) + pScreenSet->standart_height + 2
  95.         + area[border_type].origin.Y + area[border_type].corner.Y));
  96.     }
  97. //////////////////////
  98. void EditLine::exe(int act)
  99.     {
  100.     Cursor curs;
  101.     mouseHideCursor();
  102.     hilite();
  103.  
  104.     e.what = act ? KEYEVENT : NOEVENT;
  105.     global_i[0] = action_type;
  106.     switch(act)
  107.     {                                         // up, dn and so on may be added
  108.     case AC_CANCEL:
  109.         e.key = (isRet(RET_REMOVE))
  110.         ? EVENT_ALT_F3 : EVENT_ESC;
  111.         break;
  112.     case AC_OK:
  113.         e.key = EVENT_F2;
  114.         break;
  115.     }
  116.  
  117.     char* temp_str = string ? strdup(string) : strdup("");  // reserv copy
  118.  
  119.     string = (char*)realloc(string, 256);   // maximum, before exiting function
  120.     memset(string, '\0', 256);              // it will be reallocated
  121.  
  122.     strcpy(string, temp_str);
  123.     int cur_pos = 0;                    // current pos in string
  124.     int vis_pos = 0;                    // output begins from this position
  125.     settextjustify(LEFT_TEXT, BOTTOM_TEXT);
  126.  
  127.     curs.set_cursor(screenXL(xy.X) + area[border_type].origin.X,
  128.             screenYT(xy.Y) + pScreenSet->standart_height
  129.             + area[border_type].origin.Y);
  130.     curs.show_cursor();
  131.  
  132.     while(1)
  133.     {
  134.     if(!act)     // if act == 0 - we wait the event, else (f.e. CANCEL
  135.              // button pressed) - we process act, not event
  136.         {
  137.         mouseShowCursor();
  138.         get_event();
  139.         mouseHideCursor();
  140.         }
  141.  
  142.     int x = getx();    int y = gety();
  143.  
  144.     curs.set_cursor(screenXL(xy.X + cur_pos - vis_pos)
  145.         + area[border_type].origin.X,
  146.            screenYT(xy.Y) + pScreenSet->standart_height
  147.         + area[border_type].origin.Y);
  148.     curs.hide_cursor();
  149.     ::moveto(x, y);
  150.  
  151.     if(e.mouse1() || e.mouse2())   // mouse pressed
  152.         {
  153.         global_i[0] = 0;
  154.         break;
  155.         }
  156.     else
  157.         {
  158.         if(e.is_control())         // not visible char
  159.         switch(e.key)
  160.             {
  161.             case EVENT_F1: return;
  162.             case EVENT_LEFT: left(&cur_pos, &vis_pos); break;
  163.             case EVENT_RIGHT: right(&cur_pos, &vis_pos); break;
  164.             case EVENT_HOME: home(&cur_pos, &vis_pos); break;
  165.             case EVENT_END: end(&cur_pos, &vis_pos); break;
  166.  
  167.             case EVENT_DEL: del(&cur_pos, &vis_pos);  break;
  168.             case EVENT_BKSP: bksp(&cur_pos, &vis_pos); break;
  169.             case EVENT_INS: ins = !ins; break;
  170.             case EVENT_F10:
  171.             case EVENT_ESC: delete string; global_i[0] = 0;
  172.             string = strdup(temp_str); // don't change string
  173.             case EVENT_TAB:
  174.             case EVENT_F6:
  175.             case EVENT_F2:
  176.             case EVENT_ALT_F3:
  177.             case EVENT_ALT_F4:
  178.             case EVENT_ALT_TAB:
  179.             case EVENT_RETURN:
  180.             string =
  181.                 (char*)realloc(string, strlen(string) + 2);
  182.  
  183.             delete temp_str;
  184.             unhilite();
  185.             delete global[global_num];
  186.             if(global_num)
  187.                 delete global[0];
  188.             global[global_num] = strdup(string);
  189.             if(global_num)
  190.                 global[0] = strdup(string);
  191.             return;
  192.             }
  193.         else
  194.         if(e.is_char())   // visible char
  195.             {
  196.             outkey = e.key;
  197.             draw_char(&cur_pos, &vis_pos);
  198.             }
  199.  
  200.         }
  201.     x = getx();       // new coords recalculation
  202.     y = gety();
  203.     curs.set_cursor(screenXL(xy.X + cur_pos - vis_pos)
  204.         + area[border_type].origin.X,
  205.         screenYT(xy.Y) + pScreenSet->standart_height
  206.         + area[border_type].origin.Y);
  207.     curs.show_cursor();
  208.     moveto(x, y);
  209.     }
  210. // if mouse pressed outside - we keep the edited string
  211.  
  212.     string = (char*)realloc(string, strlen(string) + 2);
  213.     delete temp_str;
  214.     unhilite();
  215.     delete global[global_num]; global[global_num] = strdup(string);
  216.     delete global[0]; global[0] = strdup(string);
  217.     return;
  218.     }
  219. //////////////////////
  220. void EditLine::draw_char(int* cur_pos, int* vis_pos)
  221.     {
  222.     int tmp;
  223.     int start = 0;         // for length determination
  224.     int used = strlen(string);
  225.     if(used < maxlen || !ins)
  226.     {
  227.     insert(cur_pos);
  228.     if(*cur_pos - *vis_pos >= len)  // shift all string 1 char left
  229.         tmp = ++(*vis_pos);
  230.     else
  231.         {
  232.         tmp = *cur_pos;
  233.         start = *cur_pos - *vis_pos;
  234.         }
  235.     redraw_string(loc(xy.X + start, xy.Y), tmp, start);
  236.     }
  237.     if((used < maxlen && *cur_pos < maxlen - 1 && ins)
  238.     || (*cur_pos < maxlen - 1 && (!ins)))
  239.     (*cur_pos)++;
  240.     }
  241. //////////////////////////////
  242. void EditLine::del(int* cur_pos, int* vis_pos)
  243.     {
  244.     int i;
  245.     for(i = *cur_pos; i <= strlen(string); i++)
  246.     string[i] = string[i + 1];
  247.     redraw_string(xy, *vis_pos);
  248.     }
  249.  
  250. ////////////////////////////////
  251. void EditLine::left(int* cur_pos, int* vis_pos)
  252.     {
  253.     if(*cur_pos > 0)
  254.     (*cur_pos)--;
  255.  
  256.     if(*cur_pos < *vis_pos)
  257.     {
  258.     (*vis_pos)--;
  259.     redraw_string(xy, *vis_pos);
  260.     }
  261.     }
  262. ///////////////////////////////
  263. void EditLine::right(int* cur_pos, int* vis_pos)
  264.     {
  265.     if(*cur_pos < maxlen - 1 && *cur_pos < strlen(string))
  266.     (*cur_pos)++;
  267.  
  268.     if(*cur_pos > *vis_pos + len && *cur_pos <= strlen(string))
  269.     {
  270.     (*vis_pos)++;
  271.     redraw_string(xy, *vis_pos);
  272.     }
  273.     }
  274.  
  275.  
  276. ////////////////////////////////
  277. void EditLine::insert(int* cur_pos)
  278.     {
  279.     int l = strlen(string);
  280.     if(ins)
  281.     for(int i = l; i > *cur_pos; i--)
  282.         string[i] = string[i - 1];
  283.     string[*cur_pos] = outkey;
  284.     }
  285. /////////////////////////////////
  286. /*
  287. void main()
  288.     {
  289.     if(!init_KNOW_HOW())
  290.         return;
  291.     setfillstyle(SOLID_FILL, pColorSet->colors.BAK_COLOR);
  292.     bar(0, 0, getmaxx(), getmaxy());
  293.  
  294.     EditLine e(loc(10, 10), 40, 50, SHOW_BORDER, 17, 1);
  295.     e.put_string("Hello, WORLD !");
  296.     e.show();
  297.     e.exe();
  298.     close_KNOW_HOW();
  299.     closegraph();
  300.     }
  301. */